package cn.iocoder.yudao.module.iot.gateway.protocol.tcp.router.handler;

import cn.hutool.core.map.MapUtil;
import cn.iocoder.yudao.module.iot.core.biz.dto.IotDeviceRespDTO;
import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
import cn.iocoder.yudao.module.iot.gateway.protocol.tcp.manager.IotTcpConnectionManager;
import cn.iocoder.yudao.module.iot.gateway.service.device.IotDeviceService;
import cn.iocoder.yudao.module.iot.gateway.service.device.message.IotDeviceMessageService;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.net.NetSocket;
import lombok.extern.slf4j.Slf4j;

import static cn.iocoder.yudao.module.iot.gateway.protocol.tcp.router.IotTcpUpstreamHandler.AUTH_METHOD;

/**
 * 协议处理器基类，提供公共方法
 */
@Slf4j
public abstract class BaseProtocolHandler implements ProtocolHandler {

    /**
     * 发送响应消息
     *
     * @param socket    网络连接
     * @param success   是否成功
     * @param message   消息
     * @param requestId 请求 ID
     * @param codecType 消息编解码类型
     */
    protected void sendResponse(IotDeviceMessageService deviceMessageService, NetSocket socket, boolean success, String message, String requestId, String codecType) {
        try {
            Object responseData = MapUtil.builder()
                    .put("success", success)
                    .put("message", message)
                    .build();

            int code = success ? 0 : 401;
            IotDeviceMessage responseMessage = IotDeviceMessage.replyOf(requestId, AUTH_METHOD, responseData,
                    code, message);

            byte[] encodedData = deviceMessageService.encodeDeviceMessage(responseMessage, codecType);
            socket.write(Buffer.buffer(encodedData));

        } catch (Exception e) {
            log.error("[sendResponse][发送响应失败，requestId: {}]", requestId, e);
        }
    }

    /**
     * 发送错误响应
     */
    protected void sendErrorResponse(IotDeviceMessageService deviceMessageService, NetSocket socket, String requestId, String errorMessage, String codecType) {
        if (requestId != null) {
            sendResponse(deviceMessageService, socket, false, errorMessage, requestId, codecType);
        } else {
            log.warn("[sendErrorResponse][请求ID为空，无法发送错误响应: {}]", errorMessage);
        }
    }

    /**
     * 发送成功响应
     */
    protected void sendSuccessResponse(IotDeviceMessageService deviceMessageService, NetSocket socket, String requestId, String message, String codecType) {
        sendResponse(deviceMessageService, socket, true, message, requestId, codecType);
    }

    /**
     * 注册连接信息
     *
     * @param socket    网络连接
     * @param device    设备
     * @param clientId  客户端 ID
     * @param codecType 消息编解码类型
     */
    protected void registerConnection(IotTcpConnectionManager connectionManager, NetSocket socket, IotDeviceRespDTO device,
                                    String clientId, String codecType) {
        IotTcpConnectionManager.ConnectionInfo connectionInfo = new IotTcpConnectionManager.ConnectionInfo()
                .setDeviceId(device.getId())
                .setProductKey(device.getProductKey())
                .setDeviceName(device.getDeviceName())
                .setClientId(clientId)
                .setCodecType(codecType)
                .setAuthenticated(true);
        // 注册连接
        connectionManager.registerConnection(socket, device.getId(), connectionInfo);
    }
}
